package com.sf.marathon.soul.core.base.advice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.sf.marathon.soul.core.base.BusinessException;
import com.sf.marathon.soul.core.base.JsonResult;
import com.sf.marathon.soul.core.base.ResultCodeEnum;

/**
 * @author liutao<br>
 *         DefaultExceptionHandler<br>
 *         controller默认的异常处理<br>
 */
@ControllerAdvice
public class DefaultExceptionHandler {

    Logger logger = LoggerFactory.getLogger(getClass());
    private static final String ERROR_LABEL = ">>>>>>>>Error:";

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public JsonResult<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logger.error(ERROR_LABEL, e);
        JsonResult<String> result = new JsonResult(ResultCodeEnum.NOT_FOUND);
        return result;
    }

    /**
     * 统一 异常处理返回
     * 继承了BaseCrudController的controller无需再 try catch
     *
     * @param e   异常
     * @param req http请求 http请求
     * @return resultMap 封装的结果集map
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public JsonResult<String> handleException(Exception e, HttpServletRequest req, HttpServletResponse response) {
        JsonResult<String> result = new JsonResult();
        // 业务异常
        if (e instanceof BusinessException) {
            result.setErrCode(ResultCodeEnum.INFO.value());
            result.setMessage(e.getMessage());
            logger.info(">>>>>>>>MyselfMsg: ", e);
        } else {
            // 运行异常
            result.setSuccess(false);
            result.setErrCode(ResultCodeEnum.ERROR.value());
            result.setMessage("系统内部异常，请联系管理员");
            setResponseError(e, response);
        }

        return result;
    }

    /**
     * 设置返回错误
     *
     * @param e        exception
     * @param response http响应
     */
    private void setResponseError(Exception e, HttpServletResponse response) {
        logger.error(">>>>>>>>Error:", e);
        // 异常统一返回500状态
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }

}
